#ifndef SERIAL_H
#define SERIAL_H

#include <boost/asio.hpp>
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <fstream>
#include <iomanip>
#include <chrono>
#include <functional>

class SerialWrapper
{
public:
    // 定义的回调函数模板，当每次主函数文件serial_socket.cpp中的speed_thread线程触发calculate_speed函数时，都会执行
    using SpeedCallback = std::function<void(int64_t, int, double, int)>;
    // 窗口的构造函数，传入串口号、波特率、数据位、奇偶校验位、停止位。看一看主函数文件serial_socket.cpp中实例化该对象的传入的值，就是一般情况下传入的值
    SerialWrapper(const std::string &port, unsigned int baudrate, boost::asio::serial_port_base::character_size bytesize,
                  boost::asio::serial_port_base::parity parity, boost::asio::serial_port_base::stop_bits stopbits);
    // 查看是否存在csv文件，不存在则创建
    void ensure_file_exists(const char* file_name);
    // 打开串口
    bool open_serial();
    void close();
    // 写数据
    void write_data(const std::vector<uint8_t> &data);
    // 读数据
    void read_data();
    // 通过100ms前后测量的距离值计算平均速度
    void calculate_speed(SpeedCallback callback);

private:
    // 处理接收到的数据，当数据满足开头是 01 03 02 时，才认为是有效数据
    void process_received_data(uint8_t *data, size_t length);
    // 将数据保存到csv文件。如果文件存在就保存数据，如果不存在就直接过，不保存数据
    void save_to_csv(int64_t timestamp, int measurement, double time_diff, double speed, int dir);
    // 将停止位boost::asio::serial_port_base::stop_bits类型转为字符串
    std::string stop_bits_to_string(boost::asio::serial_port_base::stop_bits stopbits);
    // 将奇偶校验位boost::asio::serial_port_base::parity类型转为字符串
    std::string parity_to_string(boost::asio::serial_port_base::parity parity);

    std::string filename;
    std::string port;
    unsigned int baudrate;
    boost::asio::serial_port_base::character_size bytesize;
    boost::asio::serial_port_base::parity parity;
    boost::asio::serial_port_base::stop_bits stopbits;

    boost::asio::io_service io;
    boost::asio::serial_port serial;
    std::vector<uint8_t> data_queue;
    std::mutex data_mutex;
    bool running = true;

    int last_measurement = 0;
    int current_measurement = 0;
    std::chrono::steady_clock::time_point last_time;
    std::chrono::steady_clock::time_point current_time;
    // 每100ms发一次读距离的指令，并算一次速度
    const int measure_interval = 100; // milliseconds
};

#endif // SERIAL_H
